<?php

namespace app\user\tools\tencent;

use app\admin\logic\system\Config as SystemConfig;
use app\common\exception\LogicException;
use app\user\model\user\Account;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Profile\{ClientProfile, HttpProfile};
use TencentCloud\Iai\V20200303\IaiClient;
use TencentCloud\Iai\V20200303\Models\{CreateGroupRequest,
    CreateGroupResponse,
    CreatePersonRequest,
    CreatePersonResponse,
    DeletePersonRequest,
    DeletePersonResponse,
    GetGroupInfoRequest,
    VerifyPersonRequest,
    VerifyPersonResponse};

/**
 * 腾讯云人脸识别类
 * Author 亓官雨树<lucky.max@foxmail.com>
 * Date 2021-11-26
 */
class Face
{
    // 疑似人员，默认4，很高的同一人判断要求（十万一误识别率）
    const UNIQUEPERSONCONTROL = 4;
    // 图片质量控制，默认3，较高的质量要求
    const QUALITYCONTROL = 3;
    // 是否开启图片旋转识别支持，默认1，开启
    const NEEDROTATEDETECTION = 1;
    /**
     * 腾讯云人脸实例
     *
     * @var [type]
     */
    private $client;

    /**
     * 当前人员库
     *
     * @var string|integer
     */
    private $groupId;

    /**
     * 构造函数
     */
    public function __construct($SecretId = null, $SecretKey = null, $groupId = null)
    {
        if (!$SecretId || !$SecretKey || !$groupId) {
            // $config    = SystemConfig::get('face.config', [
            //     'scene' => []
            // ]);
            $config    = SystemConfig::get('system.onhook', ['scene' => []], request()->mhm_id, true);
            $SecretId  = $config['face_secret_id'] ?? "";
            $SecretKey = $config['face_secret_key'] ?? "";
            $groupId   = $config['face_group_id'] ?? "";
            $scene     = $config['scene'] ?? [];
        } else {
            $scene = ['course', 'exam'];
        }

        // 配置检查
        if (!$SecretId || !$SecretKey || !$groupId) {
            throw new LogicException('人脸识别服务暂不可用');
        }

        $this->groupId = $groupId;

        $cred        = new Credential($SecretId, $SecretKey);
        $httpProfile = new HttpProfile();
        $httpProfile->setEndpoint("iai.tencentcloudapi.com");

        $clientProfile = new ClientProfile();
        $clientProfile->setHttpProfile($httpProfile);
        $this->client = new IaiClient($cred, "ap-chengdu", $clientProfile);
    }

    /**
     * 创建人员库
     * $param['GroupName']    人员库名称
     * $param['GroupId']    人员库ID
     */
    public function createGroup($data): CreateGroupResponse
    {
        $param = array_merge([
            'GroupId' => $this->groupId
        ], $data);
        $req   = new CreateGroupRequest();
        $req->fromJsonString(json_encode($param));
        return $this->client->CreateGroup($req);
    }

    /**
     * 人员库信息
     * $param['GroupId']    人员库ID
     */
    public function getGroupInfo($param): string
    {
        $req = new GetGroupInfoRequest();
        $req->fromJsonString(json_encode($param));
        $resp = $this->client->GetGroupInfo($req);

        return $resp->GroupName;
    }

    /**
     * 创建人员
     * $param['GroupId']    人员库ID
     * $param['PersonName']    人员名称
     * $param['PersonId']    人员ID
     * $param['Image']        图片base64数据，base64编码后大小不可超过5M。jpg格式长边像素不可超过4000，其他格式图片长边像素不可超2000。
     * $param['UniquePersonControl']    疑似人员，默认4，很高的同一人判断要求（十万一误识别率）
     * $param['QualityControl']            图片质量控制，默认3，较高的质量要求
     * $param['NeedRotateDetection']    是否开启图片旋转识别支持，默认1，开启
     */
    public function createPerson($param): CreatePersonResponse
    {
        /** @var Account $user */
        $user = request()->user;
        // 参数
        $param = array_merge([
            'GroupId'             => $this->groupId,
            'PersonName'          => $user->nick_name,
            'PersonId'            => strval($user->id),
            'Gender'              => $user->gender,
            'UniquePersonControl' => self::UNIQUEPERSONCONTROL,
            'QualityControl'      => self::QUALITYCONTROL,
            'NeedRotateDetection' => self::NEEDROTATEDETECTION,
        ], $param);

        $req = new CreatePersonRequest();
        $req->fromJsonString(json_encode($param));
        return $this->client->CreatePerson($req);
    }

    /**
     * 人员验证
     * $param['PersonId']    人员ID
     * $param['Image']        图片base64数据
     * $param['UniquePersonControl']    疑似人员，默认4，很高的同一人判断要求（十万一误识别率）
     * $param['QualityControl']            图片质量控制，默认2，一般质量，偏亮、偏暗、模糊或一般模糊、眉毛遮挡、脸颊遮挡、下巴遮挡，超过三种的情况；
     * $param['NeedRotateDetection']    是否开启图片旋转识别支持，默认1，开启
     */
    public function verifyPerson($param): VerifyPersonResponse
    {

        /** @var Account $user */
        $user = request()->user;
        // 参数
        $param = array_merge([
            'GroupId'             => $this->groupId,
            'PersonId'            => strval($user->id),
            'QualityControl'      => self::QUALITYCONTROL,
            'NeedRotateDetection' => self::NEEDROTATEDETECTION,
        ], $param);

        $req = new VerifyPersonRequest();

        $req->fromJsonString(json_encode($param));

        return $this->client->VerifyPerson($req);
    }

    /**
     * 人员库删除人员
     * $param['PersonId']    人员ID
     */
    public function deletePerson($param): DeletePersonResponse
    {
        // try {
        $req = new DeletePersonRequest();

        $req->fromJsonString(json_encode($param));

        return $this->client->DeletePerson($req);
        // } catch (TencentCloudSDKException $e) {
        //     throw new LogicException($e->getMessage());
        // }
    }

}
